package com.tan.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.tan.domain.ProvinceCityDistrict;
import com.tan.domain.User;
import com.tan.mapper.UserMapper;
import com.tan.service.UserService;
import com.tan.test.StringToDouble;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    public static List<ProvinceCityDistrict> provinceCityDistricts;


    @Autowired
    UserMapper userMapper;


    public static int tick = 10;

    static ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("线程-").build();
    public static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            6, 10, 60, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100),
            new ThreadPoolExecutor.CallerRunsPolicy());
    private static List<String> movies =
            new ArrayList<>(
                    Arrays.asList(
                            "Forrest Gump",
                            "Titanic",
                            "Spirited Away",
                            "The Shawshank Redemption",
                            "Zootopia",
                            "Farewell ",
                            "Joker",
                            "Crawl"));

    @Async
    public CompletableFuture<List<String>> completableFutureTask(String start) {
        log.info(Thread.currentThread().getName() + " start this task");
        List<String> result = movies.stream().filter(e -> e.startsWith(start)).collect(Collectors.toList());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return CompletableFuture.completedFuture(result);

    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        List<String> words = Arrays.asList("F", "S", "J", "A", "C", "Z");
        List<Future<List<String>>> futures = new ArrayList<>();
        for (int i = 0; i < words.size(); i++) {
            futures.add(threadPoolExecutor.submit(new Task(movies, words.get(i))));
        }
        List<List<String>> result = new ArrayList<>();
        for (Future<List<String>> listFuture : futures) {
            try {
                result.add(listFuture.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
        System.out.println(result);
        System.out.println("耗时 : " + (System.currentTimeMillis() - start));
        System.out.println("这是主线程");

    }

    @Override
    @Async
    public CompletableFuture<List<User>> addUserBatch() {
        List<User> list = new ArrayList<>();
        for (int i = 0; i < 900; i++) {
            User u = new User();
            String name = StringToDouble.getStringRandom(8);
            u.setName(name);
            String mail = StringToDouble.getStringRandom(10) + "@qq.com";
            u.setEmail(mail);
            u.setAge((int) Math.random());
            list.add(u);
        }
        System.out.println(Thread.currentThread().getName()+" 新增"+list.size()+"条数据");
        return CompletableFuture.completedFuture(list);
    }
}

@Slf4j
class Task implements Callable<List<String>> {
    private List<String> movies;
    String start;

    public Task(List<String> movies, String start) {
        this.movies = movies;
        this.start = start;

    }


    @Override
    public List<String> call() throws Exception {
        log.info(Thread.currentThread().getName() + " start this task");
        List<String> result = movies.stream().filter(e -> e.startsWith(start)).collect(Collectors.toList());
        try {
            Thread.sleep(1000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return result;
    }
}


